#pragma once

#include "index_buffer.h"
#include "renderer.h"
#include "scene_exception.h"

#include <vector>

namespace krryn{
namespace scene{
	template<>
	class index_buffer<system::software_tag> : public hardware_buffer{
	public:
		typedef size_t* iterator;
		typedef size_t const* const_iterator;

		typedef krryn::core::refc_ptr<index_buffer> ptr;

		index_buffer(system::renderer<system::software_tag> &a_Renderer, size_t a_Size) : m_Size(a_Size){
			m_Indices = new size_t[a_Size];
			m_Current = m_Indices;

			memset(m_Indices, 0xba, a_Size);
		}

		~index_buffer(){
			delete m_Indices;
			m_Indices = 0;
			m_Current = 0; // don't delete m_Current, it's just an iterator
		}

		virtual void lock(lock_type a_Type){
			hardware_buffer::lock(a_Type);
		}

		virtual void unlock(){
			hardware_buffer::unlock();
		}

		void operator +=(size_t a_Index){
			if(locked() ^ write){
				throw scene_exception("Buffer must be write locked for insertion");
			}

			if(m_Current >= m_Indices + m_Size){
				throw scene_exception("Buffer out of bounds");
			}

			*m_Current++ = a_Index;
		}

		iterator begin(){ return m_Indices; }
		const_iterator begin() const{ return m_Indices; }

		iterator end(){ return m_Indices + m_Size; }
		const_iterator end() const{ return m_Indices + m_Size; }

		size_t size() const{
			return m_Size;
		}
	private:
		size_t *m_Indices;
		size_t *m_Current;

		size_t m_Size;
	};
}
}
